package com.cy.pj.sys.service.realm;

import com.cy.pj.sys.dao.SysMenuDao;
import com.cy.pj.sys.dao.SysRoleMenuDao;
import com.cy.pj.sys.dao.SysUserDao;
import com.cy.pj.sys.dao.SysUserRoleDao;
import com.cy.pj.sys.pojo.SysUser;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 定义realm类型继承授权AuthorizingRealm类型(包含认证+授权方法)
 * 假如只做认证可以直接继承认证AuthenticatingRealm(只有认证方法)
 */
@Service
public class ShiroUserRealm extends AuthorizingRealm {//AuthorizingRealm继承了AuthenticatingRealm
    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysUserRoleDao sysUserRoleDao;
    @Autowired
    private SysRoleMenuDao sysRoleMenuDao;
    @Autowired
    private SysMenuDao sysMenuDao;

    /**
     * 此方法用于获取用户的权限信息并进行封装
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//        //获取登录用户
//        SysUser user= (SysUser) principalCollection.getPrimaryPrincipal();
//        //获取登录用户的角色ID --从用户角色关系表
//        List<Integer> roleIds= sysUserRoleDao.findRoleIdByUserId(user.getId());
//        if(roleIds==null||roleIds.size()==0) throw new AuthorizationException();
//        //获取角色对应的菜单ID --角色菜单关系表
//        List<Integer> menuIds=sysRoleMenuDao.findMeneIdsByRoleId(roleIds);
//        if(menuIds==null||menuIds.size()==0) throw new AuthorizationException();
//        //获取菜单ID对应的授权标识(prermissions) --菜单表
//        List<String> permissions=sysMenuDao.findPermissions(menuIds);
//        if(permissions==null||permissions.size()==0) throw new AuthorizationException();
//        //封装数据并返回，交给SecurityManager对象
//        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
//        Set<String> setpermissions=new HashSet();
//        for (String per : setpermissions
//             ) {
//            if(per!=null&&!"".equals(per)){
//                setPermissions.add(per);
//            }
//        }
//        info.setStringPermissions(setpermissions);
//        return info;
        return null;
    }
    /**
     * 此方法用于获取用户的认证信息并进行封装
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //获取登陆时输入的用户名
        UsernamePasswordToken upToken=(UsernamePasswordToken)authenticationToken;
        String username=upToken.getUsername();
        //基于用户名查找数据库中的用户信息
        SysUser user=
                sysUserDao.findUserByUsername(username);
        //校验用户是否存在
        if(user==null)
            throw new UnknownAccountException();
        //校验用户是否被禁用
        if(user.getValid()==0)
            throw new LockedAccountException();
        //封装用户信息并返回，将信息交给securityManager进行认证
        ByteSource credentialsSalt=
                ByteSource.Util.bytes(user.getSalt());
        SimpleAuthenticationInfo info=
                        new SimpleAuthenticationInfo(
                                user,//principal (用户身份)
                                user.getPassword(),//hashedCredentials 已加密的密码
                                credentialsSalt, //credentialsSalt 加密盐
                                getName());//realName
        return info;
    }

    /***
     * SecurityManager比对密码时需要调用此方法获取加密算法相关信息
     * @return
     */
    @Override
    public CredentialsMatcher getCredentialsMatcher() {//AuthenticatingRealm中的方法
        //构建凭证匹配对象
        HashedCredentialsMatcher credentialsMatcher=
                new HashedCredentialsMatcher("MD5");//设置加密算法
        //设置加密次数
        credentialsMatcher.setHashIterations(1);
        return credentialsMatcher;
    }

}
